#include <Eigen/Dense>
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>

using namespace Eigen;
using namespace std;

int main() {
    VectorXd X1 = VectorXd::Zero(5);  // 长度为5的全0向量

    MatrixXd X2 = MatrixXd::Random(3, 3);  // 3x3 的随机数矩阵

    MatrixXd X3 = MatrixXd::Constant(3, 3, 1.5);  // 3x3 的常量矩阵

    MatrixXd X4 = MatrixXd::Zero(4, 4);  // 4x4 的全0矩阵
    std::cout << X4 << std::endl;

    MatrixXd X5 = MatrixXd::Ones(4, 4);  // 4x4 的全1矩阵

    X5.resize(2, 8);  // 调整矩阵的行列

    MatrixXd H = MatrixXd::Identity(5, 5);  // 5x5 的单位矩阵

    int r = H.rows();  //得到矩阵的行数

    int c = H.cols();  //得到矩阵的列数

    int s = H.size();  //得到矩阵元素总个数 5x5=25

    MatrixXd K = H.transpose();  // 矩阵求转置

    MatrixXd Rinv = H.inverse();  // 矩阵求逆
    printf("=============================================\n");

    Eigen::Tensor<float, 3> tensor(2, 2, 3);  // 创建一个 2x2x3 的 float 类型张量

    // 向张量中填充数据（这里使用简单的示例数据）
    // tensor默认通过列存储
    tensor.setValues(
        {{{1.0f, 2.0f, 3.0f}, {4.0f, 5.0f, 6.0f}}, {{7.0f, 8.0f, 9.0f}, {10.0f, 11.0f, 12.0f}}});

    // 打印张量的内容
    std::cout << "Tensor contents:\n" << tensor << std::endl;

    // Eigen::MatrixXf rowMajorMatrix = tensor.rowwise().reverse().eval().transpose().eval().eval();
    // // 将矩阵按行优先存储
    // std::cout << "row Tensor contents:\n"
    //           << tensor.rowwise().reverse().eval().transpose().eval().eval();

    // 手动打印张量的内容（按照填充的方式）
    for (int i = 0; i < tensor.dimension(0); ++i) {
        for (int j = 0; j < tensor.dimension(1); ++j) {
            for (int k = 0; k < tensor.dimension(2); ++k) {
                std::cout << tensor(i, j, k) << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }

    std::cout << tensor(0, 1, 0) << std::endl;

    std::cout << tensor(1, 1, 0) << std::endl;
    std::cout << tensor(1, 1, 2) << std::endl;

    Eigen::Tensor<float, 3> tensor2(2, 2, 3);  // 创建一个 2x2x3 的 float 类型张量

    // 填充示例数据到张量中,示例 numpy操作 [1,1]
    tensor2.setValues(
        {{{1.0f, 2.0f, 3.0f}, {4.0f, 5.0f, 6.0f}}, {{7.0f, 8.0f, 9.0f}, {10.0f, 11.0f, 12.0f}}});

    int row_index = 1;  // 第一个索引
    int col_index = 1;  // 第二个索引

    // 获取指定索引的所有值
    Eigen::array<Eigen::Index, 3> offsets = {row_index, col_index, 0};
    Eigen::array<Eigen::Index, 3> extents = {1, 1, tensor2.dimension(2)};

    Eigen::Tensor<float, 1> extractedValues =
        tensor2.slice(offsets, extents)
            .reshape(Eigen::array<Eigen::Index, 1>({tensor2.dimension(2)}));

    // 输出结果
    std::cout << "Values at index [1,1]:\n" << extractedValues << std::endl;

    return 0;
}
